#include <string>
#include "BD.h"

BD::BD(const BD& other) 
	:m_cap(other.m_n), m_n(other.m_n), m_employee(new Pair* [other.m_n])
{
	for (size_t i = 0; i < m_n; i++)
	{ 
		m_employee[i] = new Pair(*other.m_employee[i]);		
	}
}

BD::BD(BD&& other)
	:m_cap(other.m_n), m_n(other.m_n)
{
	m_employee = other.m_employee; //������ �������� ������ (��������)
	other.m_n = other.m_cap = 0;//
	other.m_employee = nullptr;//�������, ��� � ������� ��� (������ ��� �������)
}

//destructor
BD::~BD()
{
	for (size_t i = 0; i < m_n; i++)
	{ 
		delete m_employee[i];
		m_employee[i] = nullptr;
	} 

	delete[]m_employee;
	m_employee = nullptr;
}

// ���������� ����������� � ����
void BD::Add_employee(const char* name, const Data& data)
{
	for (size_t i = 0; i < m_n; i++)
	{
		if (m_employee[i]->m_name == name)
		{(*m_employee[i]).m_data = data;}
	}

	if (m_n == m_cap) //BD full
	{
		m_cap++;//add capacity 
		Pair** tmp = new Pair * [m_cap];//�������� ������ ��� ����� ������
		
		if (m_cap > 1)
		{
			for (size_t i = 0; i < m_n; i++)
			{tmp[i] = m_employee[i];} //������������ �� ������� � �����			 
			delete[] m_employee; //������� ������			
		}
		m_employee = tmp;//������������� ���������
	}
	m_employee[m_n] = new Pair(name, data);//������� ����� � ��������� �� ���������
	m_n++;

}
void BD::Add_employee(const char* name)
{
	for (size_t i = 0; i < m_n; i++)
	{
		if (m_employee[i]->m_name == name){return;}
	}

	if (m_n == m_cap) //BD full
	{
		m_cap++;//add capacity 
		Pair** tmp = new Pair * [m_cap];//�������� ������ ��� ����� ������
		
		if (m_cap > 1)
		{
			for (size_t i = 0; i < m_n; i++)
			{
				tmp[i] = std::move(m_employee[i]); //������������ �� ������� � �����
			}
			delete[] m_employee; //������� ������			
		}		
		m_employee = std::move(tmp); // ������������� ���������
	}		
	m_employee[m_n] = new Pair(name);//������� ����� � ��������� �� ���������
	m_n++;	
}

//���������� ���������� �� ����
void BD::Dell_employee(const char* name)
{
	for (size_t i = 0; i < m_n; i++)
	{
		if (m_employee[i]->m_name == name)
		{
			//dell data
			delete/*[] */m_employee[i];//Pair
			m_employee[i] = nullptr;
			
			//sort BD
			for (size_t j = i+1; j < m_n; i++,j++)
			{
				m_employee[i] = m_employee[j];//���������� ���������
			}
			//����� ��������� � �������������
			m_n--; 	
			//�������� ��������� - ��� ������
			m_employee[m_n] = nullptr;				
		}
	}	
}

BD& BD::operator=(const BD& other)
{
	if (this != &other)
	{
		//clear data
		for (size_t i = 0; i < m_n; i++)
		{
			delete m_employee[i];
			m_employee[i] = nullptr;
		}		

		if (m_cap < other.m_n)
		{	//���� ������� ������ ��� ������ ����������
			m_cap = other.m_n;//set capacity 
			delete[]m_employee;
			m_employee = new Pair * [m_cap];			
		}
		
		//copy data
		m_n = other.m_n;
		for (size_t i = 0; i < m_n; i++)
		{
			m_employee[i] = new Pair(*other.m_employee[i]);//3d var more effection
		}		
	}	
	
	return *this;
}

BD& BD::operator=(BD&& other)
{
	if (this != &other)
	{
		///clear data
		for (size_t i = 0; i < m_n; i++)
		{
			delete m_employee[i];
			m_employee[i] = nullptr;
		}

		delete[]m_employee;

		//copy data
		m_cap = m_n = other.m_n;
		m_employee = other.m_employee; //������ �������� ������ (��������)
		other.m_n = other.m_cap = 0;
		other.m_employee = nullptr;//�������, ��� � ������� ��� (������ ��� �������)		
	}
	return *this;
}

//operator[]
Data& BD::operator[](const char* Str)
{// TODO: insert return statement here
		for (size_t i = 0; i < m_n; i++)
		{
			if (m_employee[i]->m_name == Str)
			{
				return (*m_employee[i]).m_data;
			}
		}
		//check m_cap:
		//if full then add capacity & add new pair 
		//else add new pair in BD

		this->Add_employee(Str);
		return (*m_employee[m_n - 1]).m_data;	
}

//Data& BD::operator[](const char* Str) const
//{
//	return (*m_employee[m_n - 1]).m_data;
//}

std::ostream& operator<<(std::ostream& os, const BD& m_bd)
{
	for (size_t i = 0; i < m_bd.m_n; i++)
	{
		os << *m_bd.m_employee[i] << std::endl;
	}
	
	return os;
}